/**
 * @Author wangfan
 * @Date 2016/9/30 14:08
 */

package cn.ac.big.bigd.api.controller;


import cn.ac.big.bigd.bigsearch.ESFactory;
import cn.ac.big.bigd.bigsearch.service.BigSearchService;
import cn.ac.big.bigd.constant.ResultStatus;
import cn.ac.big.bigd.dao.*;
import cn.ac.big.bigd.dto.Result;
import cn.ac.big.bigd.gsa.service.GsaServive;
import cn.ac.big.bigd.model.generate.Nucleotide;
import cn.ac.big.bigd.model.generate.*;
import cn.ac.big.bigd.model.submit.Submission;
import cn.ac.big.bigd.service.ScriptService;
import cn.ac.big.bigd.service.StatsService;
import cn.ac.big.bigd.service.SubmissionService;
import cn.ac.big.bigd.transfer.BigFileCopy;
import cn.ac.big.bigd.util.*;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.Transient;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("api/submission")
public class SubmitController {


    private static final Logger logger = LoggerFactory.getLogger(SubmitController.class);
    @Autowired
    GsaServive gsaServive;
    @Autowired
    BigSearchService bigSearchService;
    @Autowired
    SubmissionService submissionService;
    @Autowired
    SubmissionDao submissionDao;
    @Autowired
    NewAssemblyDao newAssemblyDao;
    @Autowired
    NewGenomeDao newGenomeDao;
    @Autowired
    NewAnnotationDao newAnnotationDao;
    @Autowired
    NucleotideDao nucleotideDao;

    @Autowired
    NewAnnotationDetailDao newAnnotationDetailDao;
    @Autowired
    NewStatisticsDao newStatisticsDao;
    @Autowired
    ScriptService scriptService;
    @Autowired
    StatsService statsService;

    @Value("${app.path}")
    private String path;


    /**
     * 根据用户单点登录账户id，与任务id进行自动化审核，统计
     */
    @RequestMapping(value = "{casId}/{id}", method = RequestMethod.GET)
    public Result auto(@PathVariable String casId, @PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("cadID" + casId);
        logger.info("id" + id);
        response.setHeader("Access-Control-Allow-Origin", "*");

        Submission submission = submissionService.findById(id);
        if (submission.getSubStatus() != Status.PENDING) {
            return new Result(ResultStatus.ERROR, "status not pending  error", submission.getUser().getEmail());
        }
        //文件上传路径
        String uploadPath = "D:/GWH/" + submission.getMissionId() + "/";
        if ("remote".equals(path)) {
            uploadPath = "/disk3/" + casId.substring(0, 1) + "/" + casId.substring(1, 2) + "/" + casId + "/GWH/" + submission.getMissionId() + "/";
        }
        logger.info("uploadPath : " + uploadPath);

        //目标文件保存路径,处理路径
        String savePath = "D:/GWH2/" + submission.getMissionId() + "/";
        if ("remote".equals(path)) {
            savePath = "/disk2/gwhfileprocess/" + submission.getMissionId() + "/";
        }
        logger.info("savePath : " + savePath);
        File file = new File(uploadPath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File f = files[i];
                String uploadFilePath = f.getAbsolutePath();
                logger.info(uploadFilePath);
                String FileName = f.getName();
                logger.info(FileName);
                String destPath = savePath + "" + FileName;
                logger.info(destPath);
                if (BigFileCopy.copyByChannelToChannel(uploadFilePath, destPath) == 1) {
                    logger.info("文件转移成功");
                } else {
                    return new Result(ResultStatus.ERROR);
                }


            }
        }

        logger.info("start generate qc  script....");

        if (scriptService.outQcScript(submission, savePath, savePath + "" + submission.getMissionId() + ".sh")) {
            logger.info("end generate qc  script....");
        } else {
            return new Result(ResultStatus.ERROR, "generate qc script error", submission.getUser().getEmail());
        }
        submission.setSubStatus(Status.PROCESSING);//修改状态为正在处理
        submission.setUpdateTime(new Date());
        submissionService.save(submission);

        logger.info("start execute dsub qc  script....");
        String[] args = new String[]{"dsub", savePath + "" + submission.getMissionId() + ".sh"};
        String  jobId=scriptService.getProcessJobId(args);
        if (null!=jobId) {
            logger.info("end  dsub  qc  script....");
        } else {
            return new Result(ResultStatus.ERROR, "dsub qc script  error", submission.getUser().getEmail());
        }


        //判断sh脚本是否运行结束
        if (scriptService.isDsubJobFinished(jobId, savePath)) {
            logger.info("finish job:" + submission.getMissionId());
        } else {
            logger.info("qstat error");
            return new Result(ResultStatus.ERROR, "qstat error", submission.getUser().getEmail());
        }
        String errFilePath = savePath + "" + submission.getMissionId() + ".err";
        File errFile = new File(errFilePath);
        String logFilePath = savePath + "" + submission.getMissionId() + ".log";
        File logFile = new File(logFilePath);
        String outFilePath = savePath + "" + submission.getMissionId() + ".out";
        File outFile = new File(outFilePath);
        String userFilePath = savePath + "" + submission.getMissionId() + ".user";
        File userFile = new File(userFilePath);
        List<File> list = new ArrayList<>();
        logger.info(outFile.exists() + "");
        logger.info(outFile.getAbsolutePath() + "");

        if (outFile.isFile() && outFile.exists()) { //判断out文件是否存在
            InputStreamReader read = new InputStreamReader(
                    new FileInputStream(outFile));
            BufferedReader bufferedReader = new BufferedReader(read);
            String outStr = "";
            String lineTxt = null;
            while ((lineTxt = bufferedReader.readLine()) != null) {
                logger.info(lineTxt);
                outStr = outStr + lineTxt + "\n";
            }
            read.close();
            logger.info(outStr);
            if (outStr.contains("DoneFinished!")) {
                logger.info("outFile normal....");

            } else {
                logger.info("outFile abnormal....");
                //非正常结束发送邮件给管理员
                sendAbnormalEmail(submission, savePath);

                return new Result(ResultStatus.ERROR, "has error", submission.getUser().getEmail());
            }

        }

        if (logFile.isFile() && logFile.exists() && logFile.length() == 0) {
            logger.info("logFile normal....");

        } else {
            logger.info("logFile abnormal....");
            //非正常结束发送邮件给管理员
            sendAbnormalEmail(submission, savePath);
            return new Result(ResultStatus.ERROR, "logFile has error", submission.getUser().getEmail());
        }

        if (errFile.isFile() && errFile.exists()) {
            if (errFile.length() > 0) {
                list.add(errFile);
                logger.info("errFile normal but has error....");
            } else {
                logger.info("errFile normal and  no error....");
            }


        } else {
            logger.info("errFile is not exist....");
            //非正常结束发送邮件给管理员
            sendAbnormalEmail(submission, savePath);
            return new Result(ResultStatus.ERROR, "has error", submission.getUser().getEmail());
        }

        if (submission.getFiles().isCheckProcesses()) {//运行了python脚本
            if (userFile.isFile() && userFile.exists()) {
                if (userFile.length() > 0) {
                    list.add(userFile);
                    logger.info("userFile normal but has error....");
                } else {
                    logger.info("userFile normal and  no error....");
                }


            } else {
                logger.info("userFile is not exist....");
                //非正常结束发送邮件给管理员
                sendAbnormalEmail(submission, savePath);
                return new Result(ResultStatus.ERROR, "has error", submission.getUser().getEmail());
            }

        }


        if (list.size() > 0) {//存在报错文件，以附件形式发送给用户
            logger.info("send attach email....");
            StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;font: bold 14px/22px arial,sans-serif;\">Dear " + submission.getSubmitter().getFirstName() + " " + submission.getSubmitter().getLastName() + ","
                    + "<br/>"
                    + "<br/>We have received your WGS submission."
                    + "<br/><table border=\"1\" ><tr> <th>Submission Title </th><th>Submission ID </th><th>BioProject</th><th>Biosample</th></tr>"
                    + "<tr><td>" + submission.getGeneralInfo().getSubmissoinTitle() + "</td><td>" + submission.getMissionId() + "</td><td>" + submission.getGeneralInfo().getBioProjectAccession() + "</td><td>" + submission.getGeneralInfo().getBioSampleAccession() + "</td></tr></table>"
                    + "<br/>After validation check processing, we have come across some issues which require your attention."
                    + "<br/><br/>You need to check and be sure that all errors in the attached report files are fixed."
                    + "<br/><br/>Please resubmit the corrected files at your convenience. To resubmit the corrected files, do not create a new submission. Instead, log back into genome submission portal, <a href='http://bigd.big.ac.cn/gwh/submit/submission'>http://bigd.big.ac.cn/gwh/submit/submission</a>. Revise the genome submission by clicking the corresponding submission ID, which is editable. Delete the files exist errors and upload replacement files, then click submit. Note that you need to reconfirm metadata from step1 to step6 when you revise your submission."
                    + "<br/><br/>If you submit file by ftp, please log back into genome submission portal (<a href='http://bigd.big.ac.cn/gwh/submit/submission'>http://bigd.big.ac.cn/gwh/submit/submission</a>) after file submission, and click the \"Finish upload\" button in \"My Submissions\" list to inform us to check your submission."

                    + "<br/><br/>Please send email to gwh@big.ac.cn if you have any question or revision about your submission!"
                    + "<br/><br/>User:" + submission.getSubmitter().getEmail()
                    + "<br/><br/>Sincerely,<br/>GWH team<br/><br/></div>");

            // 发送邮件
            EmailUtils.sendHtmlMailWithAttach("Feedback validation about " + submission.getMissionId() + " (" + submission.getGeneralInfo().getBioProjectAccession() + "; " + submission.getGeneralInfo().getBioSampleAccession() + ")", sb.toString(),  "chenml@big.ac.cn", list);

            submission.setSubStatus(Status.STEP_ONE);//修改状态到第一步，让用户重新填写
            submission.setUpdateTime(new Date());
            submissionService.save(submission);
//            FileUtil.deleteAllFilesOfDir(new File(savePath));
            return new Result(ResultStatus.SUCCESS, "SUCCESS with file error", submission.getUser().getEmail());

        } else {

            //先生成asseccion号
            if (null == submission.getAccession()) {
                if (submission.getGeneralInfo().isUpdateSubmission() && submission.getGeneralInfo().getGenomeAccession().startsWith("GWH")) {
                    String accession = submission.getGeneralInfo().getGenomeAccession();
                    String prefix = accession.split(".")[0];
                    List<Submission> submissionList = submissionService.findByAccessionStartingWith(prefix);
                    if (submissionList.size() > 0) {
                        Submission s = submissionList.get(submissionList.size() - 1);
                        if (s.isReleased()) {
                            if (s.getAccession().contains(".")) {
                                String suffix = (Long.valueOf(s.getAccession().split(".")[1]) + 1) + "";
                                accession = prefix + "." + suffix;
                            } else {
                                accession = accession + ".1";
                            }


                        } else {
                            return new Result(ResultStatus.ERROR, "has no release version  before", submission.getUser().getEmail());
                        }
                    } else {
                        return new Result(ResultStatus.ERROR, "genome accession error", submission.getUser().getEmail());
                    }
                    submission.setAccession(accession);
                    submission = submissionService.save(submission);

                } else {

                    synchronized(this) {
                        String maxAccession = submissionDao.findMaxByAccessionDesc();
                        if(maxAccession.contains(".")){
                            maxAccession = maxAccession.split(".")[0];
                        }

                        AccessionUtil.accession = (maxAccession == null || maxAccession.equals("")) ? "GWHAAAA00000000" : maxAccession;
                    }
                    if (!AccessionUtil.accession.equals("GWHAAAA00000000")) {
                        AccessionUtil.addAcc();
                    }

                    submission.setAccession(AccessionUtil.accession);
                    submission = submissionService.save(submission);
                }
            }
            submission.setSubStatus(Status.SUCCESSFUL);//修改状态到成功
            submission.setUpdateTime(new Date());
            submissionService.save(submission);
            StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;font: bold 14px/22px arial,sans-serif;\">Dear " + submission.getSubmitter().getFirstName() + " " + submission.getSubmitter().getLastName() + ","
                    + "<br/>"
                    + "<br/>We have received your WGS submission."
                    + "<br/><table border=\"1\" ><tr><th>Submission Title </th><th>Accession </th> <th>Submission ID </th><th>BioProject</th><th>Biosample</th></tr>"
                    + "<tr><td>" + submission.getGeneralInfo().getSubmissoinTitle() + "</td><td>" + submission.getAccession() + "</td><td>" + submission.getMissionId() + "</td><td>" + submission.getGeneralInfo().getBioProjectAccession() + "</td><td>" + submission.getGeneralInfo().getBioSampleAccession() + "</td></tr></table>"
                    + "<br/>We inform that your submission has passed our current validation check."
                    + "<br/><br/>Please cite the accession number " + submission.getAccession() + " like this:"
                    + "<br/><br/>The whole genome sequence data reported in this paper have been deposited in the Genome Warehouse in BIG Data Center [1], Beijing Institute of Genomics (BIG), Chinese Academy of Sciences, under accession number " + submission.getAccession() + " that is publicly accessible at http://bigd.big.ac.cn/gwh."
                    + "<br/><br/>References:"
                    + "<br/><br/>[1] BIG Data Center Members. The BIG Data Center: from deposition to integration to translation. Nucleic Acids Res 2017, 45(D1):D18-D24."
                    + "<br/><br/>Please send email to gwh@big.ac.cn if you have any question or revision about your submission!"
                    + "<br/><br/>User:" + submission.getSubmitter().getEmail()
                    + "<br/><br/>Sincerely,<br/>GWH team<br/><br/></div>");

            // 发送成功邮件
            EmailUtils.sendHtmlMail("Accession assignment for " + submission.getMissionId() + " (" + submission.getAccession() + "; " + submission.getGeneralInfo().getBioProjectAccession() + "; " + submission.getGeneralInfo().getBioSampleAccession() + ")", sb.toString(), "gwh@big.ac.cn," + submission.getSubmitter().getEmail());


            if (scriptService.outStatsScript(submission, savePath, savePath + "" + submission.getAccession() + ".sh")) {
                logger.info("end generate stats  script....");
            } else {
                return new Result(ResultStatus.ERROR, "generate stats script error", submission.getUser().getEmail());
            }
            logger.info("start execute dsub stats  script....");
            args = new String[]{"dsub", savePath + "" + submission.getAccession() + ".sh"};
            jobId=scriptService.getProcessJobId(args);
            if (null!=jobId) {
                logger.info("end  dsub  stats  script....");
            } else {
                return new Result(ResultStatus.ERROR, "dsub stats script  error", submission.getUser().getEmail());
            }


            //审核通过后文件临时保存路径,处理路径
            String tempPath = "/disk4/gwhFileSite/" + submission.getAccession() + "/";


            File file2 = new File(savePath);
            if (file2.isDirectory()) {
                File[] files = file2.listFiles();
                for (int i = 0; i < files.length; i++) {
                    File f = files[i];
                    String uploadFilePath = f.getAbsolutePath();
                    logger.info(uploadFilePath);
                    String FileName = f.getName();
                    logger.info(FileName);
                    String destPath = tempPath + "" + FileName;
                    logger.info(destPath);
                    if (BigFileCopy.copyByChannelToChannel(uploadFilePath, destPath) == 1) {
                        logger.info("文件转移成功");
                    } else {
                        return new Result(ResultStatus.ERROR);
                    }


                }
            }
            //判断sh脚本是否运行结束
            if (scriptService.isDsubJobFinished(jobId, savePath)) {
                logger.info("finish job:" + submission.getAccession());
            } else {
                logger.info("qstat error");
                return new Result(ResultStatus.ERROR, "qstat error", submission.getUser().getEmail());
            }


            File statsOutFile = new File(savePath + "" + submission.getAccession() + ".out");
            File statsLogFile = new File(savePath + "" + submission.getAccession() + ".log");

            if (statsOutFile.isFile() && statsOutFile.exists()) { //判断out文件是否存在
                InputStreamReader read = new InputStreamReader(
                        new FileInputStream(statsOutFile));
                BufferedReader bufferedReader = new BufferedReader(read);
                String outStr = "";
                String lineTxt = null;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    logger.info(lineTxt);
                    outStr = outStr + lineTxt + "\n";
                }
                read.close();
                logger.info(outStr);
                if (outStr.contains("DoneFinished!")) {
                    logger.info("outFile normal....");

                } else {
                    logger.info("outFile abnormal....");
                    //非正常结束发送邮件给管理员
                    sendAbnormalEmail(submission, savePath);

                    return new Result(ResultStatus.ERROR, "has error", submission.getUser().getEmail());
                }

            }
            if (statsLogFile.isFile() && statsLogFile.exists() && statsLogFile.length() == 0) {
                logger.info("statsLogFile normal....");
                statsService.saveStats(submission, savePath);
            } else {
                logger.info("statsLogFile abnormal....");
                //非正常结束发送邮件给管理员
                sendAbnormalEmail(submission, savePath, savePath + "" + submission.getAccession() + ".sh");
            }









//            FileUtil.deleteAllFilesOfDir(new File(savePath)); //发布之后删除文件
            return new Result(ResultStatus.SUCCESS, "SUCCESSFUL", submission.getUser().getEmail());
        }


    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Object submission(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
        return submissionService.findById(id).getUser();

    }

    /*根据任务accession id，进行release发布*/
    @Transient
    @RequestMapping(value = "release/{id}", method = RequestMethod.GET)
    public Result release(@PathVariable String id,Boolean flag, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
//        NewAssembly assembly =newAssemblyDao.findOne(id);
        Submission submission = submissionService.findByAccession(id);
        if (null == submission || null == submission.getAccession()) {
            return new Result(ResultStatus.ERROR, "no submission", submission.getUser().getEmail());
        } else {
            if (submission.getSubStatus() == Status.SUCCESSFUL || submission.getSubStatus() == Status.RELEASED) {
                String accession = submission.getAccession();
                Date d = new Date();
//                    submission.setReleaseTime(d);
                submission.setReleased(true);
                submission.setSubStatus(Status.RELEASED);
                submissionDao.save(submission);
                NewAssembly newAssembly = newAssemblyDao.findByAccession(accession);
                if (null == newAssembly) {//没有就创建
                    return new Result(ResultStatus.ERROR, "no assembly", submission.getUser().getEmail());
                } else {

                    NewGenome newGenome = newAssembly.getNewGenome();
                    newGenome.setStatus(1);
                    newGenomeDao.save(newGenome);

                    List<String> stringList = new ArrayList<>();

                    if (submission.getFiles().getAssemblyLevel() == 2) {//draft in chromosome level
                        if (submission.getFiles().getChromsomeFrom() == 0) {
                            if(null!=submission.getFiles().getScaffoldsFromContigsFilename()) {
                                stringList.add(FileUtil.getFileName(submission.getFiles().getScaffoldsFromContigsFilename()));
                            }
                            if(null!=submission.getFiles().getChroFromScaffoldsFilename()) {
                                stringList.add(FileUtil.getFileName(submission.getFiles().getChroFromScaffoldsFilename()));
                            }
                        } else {
                            stringList.add(FileUtil.getFileName(submission.getFiles().getChroFromContigsFilename()));
                        }

                    } else if (submission.getFiles().getAssemblyLevel() == 1) {//Draft genome in scaffold level

                        if(null!=submission.getFiles().getScaffoldsFromContigsFilename()) {
                            stringList.add(FileUtil.getFileName(submission.getFiles().getScaffoldsFromContigsFilename()));
                        }
                    }


                    if (null != submission.getFiles().getAnnotationFilename()) {
                        stringList.add(submission.getAccession() + ".genome.fasta.gz");
                        newAssembly.setDNA(submission.getAccession() + ".genome.fasta.gz");

                        String savePath = "/disk2/gwhfileprocess/" + submission.getMissionId() + "/";

                        File f =new File(savePath+submission.getAccession() + ".gff.gz");
                        if(f.exists()){
                            stringList.add(submission.getAccession() + ".gff.gz");
                            newAssembly.setGFF(submission.getAccession() + ".gff.gz");
                        }
                        f =new File(savePath+submission.getAccession() + ".Protein.faa.gz");
                        if(f.exists()){
                            stringList.add(submission.getAccession() +".Protein.faa.gz");
                            newAssembly.setProtein(submission.getAccession() + ".Protein.faa.gz");
                        }
                        f =new File(savePath+submission.getAccession() + ".RNA.fasta.gz");
                        if(f.exists()){
                            stringList.add(submission.getAccession() + ".RNA.fasta.gz");
                            newAssembly.setRNA(submission.getAccession() + ".RNA.fasta.gz");
                        }
                        f =new File(savePath+submission.getAccession() + ".CDS.fasta.gz");
                        if(f.exists()){
                            stringList.add(submission.getAccession() + ".CDS.fasta.gz");
                            newAssembly.setCDS(submission.getAccession() + ".CDS.fasta.gz");
                        }
                        f =new File(savePath+submission.getAccession() + ".feature.gz");
                        if(f.exists()){
                            stringList.add(submission.getAccession() + ".feature.gz");
                            newAssembly.setFeature(submission.getAccession() + ".feature.gz");
                        }

                    } else {
                        stringList.add(submission.getAccession() + ".genome.fasta.gz");
                        newAssembly.setDNA(submission.getAccession() + ".genome.fasta.gz");
                    }
                    String type = gsaServive.getDirBySampleWithResult(submission.getGeneralInfo().getBioSampleAccession());
                    newAssembly.setType(type);
                    String assDir = newGenome.getScientificName().replaceAll(" ", "_")
                            + "_" + newAssembly.getName().replaceAll(" ", "_")
                            + "_" + submission.getAccession();
                    newAssembly.setFtpDir(type + "/" + assDir);

                    if(!newAssembly.isReleased()){
                        newAssembly.setReleasedAt(d);
                    }
                    newAssembly.setReleased(true);
                    newAssemblyDao.save(newAssembly);

                    //复制文件到ftp所在地址，。
                    String tempPath = "/disk4/gwhFileSite/" + submission.getAccession() + "/";
                    String ftpPath = "/disk1/pubftp/pub/gwh/";

                    ftpPath = ftpPath + type + "/" + assDir + "/";
                    File file2 = new File(tempPath);
                    if (file2.isDirectory()) {
                        File[] files = file2.listFiles();
                        for (int i = 0; i < files.length; i++) {
                            File f = files[i];
                            String uploadFilePath = f.getAbsolutePath();
                            logger.info(uploadFilePath);
                            String fileName = f.getName();
                            logger.info(fileName);

                            if (stringList.contains(fileName)) {
                                String destPath = ftpPath + "" + fileName;
                                logger.info(ftpPath);
                                if (BigFileCopy.copyByChannelToChannel(uploadFilePath, destPath) == 1) {
                                    logger.info("文件转移成功");
                                } else {
                                    return new Result(ResultStatus.ERROR);
                                }
                            }


                        }
                    }

                   if(!bigSearchService.createGwhAccession(accession)){
                       return new Result(ResultStatus.ERROR, "RELEASE BIGSEARCH ERROR", submission.getUser().getEmail());
                   }



                    return new Result(ResultStatus.SUCCESS, "RELEASE SUCCESSFUL", submission.getUser().getEmail());
                }
            } else {
                return new Result(ResultStatus.ERROR, "status not successful or release", submission.getUser().getEmail());
            }


        }


    }


    /*根据任务id，进行Accession号分配，修改状态successful*/
    @Transient
    @RequestMapping(value = "successful/{id}", method = RequestMethod.GET)
    public Result successful(@PathVariable Long id,Boolean flag, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        Submission submission = submissionService.findById(id);
        if (null == submission ) {
            return new Result(ResultStatus.ERROR, "no submission", submission.getUser().getEmail());
        }else if( null!= submission.getAccession()){
            submission.setSubStatus(Status.SUCCESSFUL);
            submissionDao.save(submission);
            return new Result(ResultStatus.SUCCESS, "update SUCCESSFUL", submission.getUser().getEmail());
        }   else{
            if (submission.getSubStatus() == Status.PROCESSING ) {

                //先生成asseccion号
                if (null == submission.getAccession()) {
                    if (submission.getGeneralInfo().isUpdateSubmission() && submission.getGeneralInfo().getGenomeAccession().startsWith("GWH")) {
                        String accession = submission.getGeneralInfo().getGenomeAccession();
                        String prefix = accession.split(".")[0];
                        List<Submission> submissionList = submissionService.findByAccessionStartingWith(prefix);
                        if (submissionList.size() > 0) {
                            Submission s = submissionList.get(submissionList.size() - 1);
                            if (s.isReleased()) {
                                if (s.getAccession().contains(".")) {
                                    String suffix = (Long.valueOf(s.getAccession().split(".")[1]) + 1) + "";
                                    accession = prefix + "." + suffix;
                                } else {
                                    accession = accession + ".1";
                                }


                            } else {
                                return new Result(ResultStatus.ERROR, "has no release version  before", submission.getUser().getEmail());
                            }
                        } else {
                            return new Result(ResultStatus.ERROR, "genome accession error", submission.getUser().getEmail());
                        }
                        submission.setAccession(accession);
                        submission = submissionService.save(submission);

                    } else {

                        synchronized(this) {
                            String maxAccession = submissionDao.findMaxByAccessionDesc();
                            if(maxAccession.contains(".")){
                                maxAccession = maxAccession.split(".")[0];
                            }

                            AccessionUtil.accession = (maxAccession == null || maxAccession.equals("")) ? "GWHAAAA00000000" : maxAccession;
                        }
                        if (!AccessionUtil.accession.equals("GWHAAAA00000000")) {
                            AccessionUtil.addAcc();
                        }

                        submission.setAccession(AccessionUtil.accession);
                        submission = submissionService.save(submission);
                    }
                }
                submission.setSubStatus(Status.SUCCESSFUL);//修改状态到成功
                submission.setUpdateTime(new Date());
                submissionService.save(submission);
                StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;font: bold 14px/22px arial,sans-serif;\">Dear " + submission.getSubmitter().getFirstName() + " " + submission.getSubmitter().getLastName() + ","
                        + "<br/>"
                        + "<br/>We have received your WGS submission."
                        + "<br/><table border=\"1\" ><tr><th>Submission Title </th><th>Accession </th> <th>Submission ID </th><th>BioProject</th><th>Biosample</th></tr>"
                        + "<tr><td>" + submission.getGeneralInfo().getSubmissoinTitle() + "</td><td>" + submission.getAccession() + "</td><td>" + submission.getMissionId() + "</td><td>" + submission.getGeneralInfo().getBioProjectAccession() + "</td><td>" + submission.getGeneralInfo().getBioSampleAccession() + "</td></tr></table>"
                        + "<br/>We inform that your submission has passed our current validation check."
                        + "<br/><br/>Please cite the accession number " + submission.getAccession() + " like this:"
                        + "<br/><br/>The whole genome sequence data reported in this paper have been deposited in the Genome Warehouse in BIG Data Center [1], Beijing Institute of Genomics (BIG), Chinese Academy of Sciences, under accession number " + submission.getAccession() + " that is publicly accessible at http://bigd.big.ac.cn/gwh."
                        + "<br/><br/>References:"
                        + "<br/><br/>[1] BIG Data Center Members. The BIG Data Center: from deposition to integration to translation. Nucleic Acids Res 2017, 45(D1):D18-D24."
                        + "<br/><br/>Please send email to gwh@big.ac.cn if you have any question or revision about your submission!"
                        + "<br/><br/>User:" + submission.getSubmitter().getEmail()
                        + "<br/><br/>Sincerely,<br/>GWH team<br/><br/></div>");


                // 发送成功邮件
                EmailUtils.sendHtmlMail("Accession assignment for " + submission.getMissionId() + " (" + submission.getAccession() + "; " + submission.getGeneralInfo().getBioProjectAccession() + "; " + submission.getGeneralInfo().getBioSampleAccession() + ")", sb.toString(), "gwh@big.ac.cn," + submission.getSubmitter().getEmail());
                return new Result(ResultStatus.SUCCESS, "SUCCESSFUL", submission.getUser().getEmail());


            } else {
                return new Result(ResultStatus.ERROR, "status not process ", submission.getUser().getEmail());
            }


        }


    }


    /*根据任务id，进行format*/
    @Transient
    @RequestMapping(value = "format/{id}", method = RequestMethod.GET)
    public Result format(@PathVariable String id,Boolean flag, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        Submission submission = submissionService.findByAccession(id);
        if (null == submission || null == submission.getAccession()) {
            return new Result(ResultStatus.ERROR, "no submission", submission.getUser().getEmail());
        } else {
            if (submission.getSubStatus() == Status.SUCCESSFUL || submission.getSubStatus() == Status.RELEASED) {

                String savePath = "/disk2/gwhfileprocess/" + submission.getMissionId() + "/";
                String accession = submission.getAccession();
                logger.info("start generate format  script....");
                if (scriptService.outFormatScript(submission, savePath, savePath + "" + submission.getMissionId() + "format.sh")) {
                    logger.info("end generate format  script....");
                } else {
                    return new Result(ResultStatus.ERROR, "generate format script error", submission.getUser().getEmail());
                }

                logger.info("start execute dsub format  script....");

                String[] args = new String[]{"dsub", savePath + "" + submission.getMissionId() + "format.sh"};
                String  jobId=scriptService.getProcessJobId(args);
                if (null!=jobId) {
                    logger.info("end  format  qc  script....");
                } else {
                    return new Result(ResultStatus.ERROR, "dsub qc script  error", submission.getUser().getEmail());
                }


                //判断sh脚本是否运行结束
                if (scriptService.isDsubJobFinished(jobId, savePath)) {
                    logger.info("finish job:" + submission.getAccession()+"format");
                } else {
                    logger.info("qstat error");
                    return new Result(ResultStatus.ERROR, "qstat error", submission.getUser().getEmail());
                }

                File f =new File(savePath+submission.getAccession()+".formatfeature");


                if(f.exists()){
                    //批量删除之前的记录
                    List<Nucleotide> oldList =nucleotideDao.findAllBySubmissionId(submission.getId());
                    nucleotideDao.delete(oldList);
                    readTabForSequence(savePath+submission.getAccession()+".formatfeature",true,submission.getId());


                }

            }else{
                return new Result(ResultStatus.ERROR, "error", submission.getUser().getEmail());
            }

        }
        return new Result(ResultStatus.SUCCESS, "success", submission.getUser().getEmail());

    }

    public void readTabForSequence(String filepath, boolean head,long id) throws Exception {
        File file = new File(filepath);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;
        if(head){
            br.readLine();
        }
        Nucleotide nucleotide =null;
        while ((line = br.readLine()) != null) { //循环读取行

            String[] result = line.split("\t",-1); //按tab分割
            nucleotide =new Nucleotide();
            nucleotide.setAccession(result[0]);
            nucleotide.setContacts(result[1]);
            nucleotide.setReferences(result[2]);
            nucleotide.setLineage(result[3]);
            nucleotide.setScientificName(result[4]);
            nucleotide.setCommonName(result[5]);
            nucleotide.setLen(result[6]);
            nucleotide.setName(result[7]);
            nucleotide.setCircular(result[8]);
            nucleotide.setComplete(result[9]);
            nucleotide.setType(result[10]);
            nucleotide.setClasss(result[11]);
            nucleotide.setGeneSymbol(result[12]);
            nucleotide.setCategory(result[13]);
            nucleotide.setChrom(result[14]);
            nucleotide.setStrand(result[15]);
            nucleotide.setStart(result[16]);
            nucleotide.setEnd(result[17]);
            nucleotide.setStarts(result[18]);
            nucleotide.setEnds(result[19]);
            nucleotide.setPseudo(result[20]);
            nucleotide.setProduct(result[21]);
            nucleotide.setOriID(result[22]);
            nucleotide.setParent(result[23]);
            nucleotide.setGenomicseq(result[24]);
            nucleotide.setRNAseq(result[25]);
            nucleotide.setCDSseq(result[26]);
            nucleotide.setProteinseq(result[27]);

            nucleotide.setSubmissionId(id);
            nucleotideDao.save(nucleotide);
        }
    }

    @Transient
    @RequestMapping(value = "calStatus/{id}", method = RequestMethod.GET)
    public Result calStatus(@PathVariable String id, Boolean flag,String type, HttpServletResponse response) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");

//        NewAssembly assembly =newAssemblyDao.findOne(id);
        Submission submission = submissionService.findByAccession(id);
        //处理路径
        String savePath = "D:/GWH2/" + submission.getMissionId() + "/";
        if ("remote".equals(path)) {
            savePath = "/disk2/gwhfileprocess/" + submission.getMissionId() + "/";
        }
        File statsLogFile = new File(savePath + "" + submission.getAccession() + ".log");

        try {
            if (null == flag || flag) {
                if (!new File(savePath + "" + submission.getAccession()).exists()) {
                    if (scriptService.outStatsScript(submission, savePath, savePath + "" + submission.getAccession() + ".sh")) {
                        logger.info("end generate stats  script....");
                    } else {
                        return new Result(ResultStatus.ERROR, "generate stats script error", submission.getUser().getEmail());
                    }

                }
                logger.info("start execute dsub stats  script....");
                String[] args = new String[]{"dsub", savePath + "" + submission.getAccession() + ".sh"};
                String  jobId=scriptService.getProcessJobId(args);
                if (null!=jobId) {
                    logger.info("end  dsub  stats  script....");
                } else {
                    return new Result(ResultStatus.ERROR, "dsub stats script  error", submission.getUser().getEmail());
                }

                //判断sh脚本是否运行结束
                if (scriptService.isDsubJobFinished(jobId, savePath)) {
                    logger.info("finish job:" + submission.getAccession());
                } else {
                    logger.info("qstat error");
                    return new Result(ResultStatus.ERROR, "qstat error", submission.getUser().getEmail());
                }

                //审核通过后文件临时保存路径,处理路径,flag=false时不复制文件

                String tempPath = "/disk4/gwhFileSite/" + submission.getAccession() + "/";
                File file2 = new File(savePath);
                if (file2.isDirectory()) {
                    File[] files = file2.listFiles();
                    for (int i = 0; i < files.length; i++) {
                        File f = files[i];
                        String uploadFilePath = f.getAbsolutePath();
                        String FileName = f.getName();
                        String destPath = tempPath + "" + FileName;
                        if (BigFileCopy.copyByChannelToChannel(uploadFilePath, destPath) == 1) {
                            logger.info("文件转移成功");
                        } else {
                            return new Result(ResultStatus.ERROR);
                        }
                    }
                }
                File statsOutFile = new File(savePath + "" + submission.getAccession() + ".out");
                statsLogFile = new File(savePath + "" + submission.getAccession() + ".log");

                if (statsOutFile.isFile() && statsOutFile.exists()) { //判断out文件是否存在
                    InputStreamReader read = new InputStreamReader(
                            new FileInputStream(statsOutFile));
                    BufferedReader bufferedReader = new BufferedReader(read);
                    String outStr = "";
                    String lineTxt = null;
                    while ((lineTxt = bufferedReader.readLine()) != null) {
                        outStr = outStr + lineTxt + "\n";
                    }
                    read.close();
                    logger.info(outStr);
                    if (outStr.contains("DoneFinished!")) {
                        logger.info("outFile normal....");
                    } else {
                        logger.info("outFile abnormal....");
                        //非正常结束发送邮件给管理员
                        sendAbnormalEmail(submission, savePath);
                        return new Result(ResultStatus.ERROR, "has error", submission.getUser().getEmail());
                    }

                }
            }

            if (statsLogFile.isFile() && statsLogFile.exists() && statsLogFile.length() == 0) {
                logger.info("statsLogFile normal....");
                statsService.saveStats(submission, savePath);//保存统计信息
            } else {
                logger.info("statsLogFile abnormal....");
                //非正常结束发送邮件给管理员
                sendAbnormalEmail(submission, savePath, savePath + "" + submission.getAccession() + ".sh");
                return new Result(ResultStatus.ERROR, "statsLogFile has error", submission.getUser().getEmail());
            }
        } catch (Exception e) {
            try {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            } catch (NoTransactionException e1) {
            }
            return new Result(ResultStatus.ERROR, e.toString(), submission.getUser().getEmail());
        }
//        FileUtil.deleteAllFilesOfDir(new File(savePath));
        return new Result(ResultStatus.SUCCESS, "success", submission.getUser().getEmail());

    }

    @RequestMapping(value = "WGS/{WGS}", method = RequestMethod.GET)
    public Object submissionByWGS(@PathVariable String WGS, HttpServletRequest request, HttpServletResponse response) throws Exception {

        return submissionService.findByMissionId(WGS).getUser();

    }


    private void sendAbnormalEmail(Submission submission, String savePath) {
        StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;font: bold 14px/22px arial,sans-serif;\">Dear Admin ,"
                + "<br/>"
                + "<br/><br/>Path:" + savePath
                + "<br/><br/>User:" + submission.getSubmitter().getEmail()
                + "<br/><br/>Sincerely,<br/>GWH team<br/><br/></div>");

        // 发送邮件
        EmailUtils.sendHtmlMail("Mission error" + submission.getMissionId() + " (" + submission.getGeneralInfo().getBioProjectAccession() + "; "

                + submission.getGeneralInfo().getBioSampleAccession() + ")", sb.toString(), "wangfan@big.ac.cn,chenml@big.ac.cn");

    }


    private void sendAbnormalEmail(Submission submission, String savePath, String script) {
        StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;font: bold 14px/22px arial,sans-serif;\">Dear Admin ,"
                + "<br/>"
                + "<br/><br/>Path:" + savePath
                + "<br/><br/>Script:" + script
                + "<br/><br/>User:" + submission.getSubmitter().getEmail()
                + "<br/><br/>Sincerely,<br/>GWH team<br/><br/></div>");

        // 发送邮件
        EmailUtils.sendHtmlMail("Mission error" + submission.getMissionId() + " (" + submission.getGeneralInfo().getBioProjectAccession() + "; "

                + submission.getGeneralInfo().getBioSampleAccession() + ")", sb.toString(), "wangfan@big.ac.cn,chenml@big.ac.cn");

    }


}
